home *** CD-ROM | disk | FTP | other *** search
- Path: newsbf02.news.aol.com!not-for-mail
- From: jwpirie@aol.com (JWPirie)
- Newsgroups: comp.lang.c++
- Subject: Re: C Programming Question
- Date: 16 Jan 1996 10:04:26 -0500
- Organization: America Online, Inc. (1-800-827-6364)
- Sender: root@newsbf02.news.aol.com
- Message-ID: <4dgepq$2tt@newsbf02.news.aol.com>
- References: <8B8E4D4.009200AFF3.uuout@bbs1984.chi.il.us>
- Reply-To: jwpirie@aol.com (JWPirie)
- NNTP-Posting-Host: newsbf02.mail.aol.com
-
- I searched high and low for a device to format my values with commas. I
- finally gave up and wrote my own code.
-
- This is in C++, so if you're just using C you're out of luck.
-
- //**********************************************************************
- // The header file, commas.h:
- class comm {
- protected:
- double x;
- public:
- comm(); // Constructors
- comm(double d);
-
- inline operator double(); // Conversion
- inline operator float();
- inline operator int();
- inline operator long();
-
- // Stream
- friend ostream& operator<<(ostream &s, comm d);
- };
-
-
- //******************************************************************
- // The implementation file, commas.cpp:
-
- comm::comm() { x = 0; }
- comm::comm(double d) { x = d; }
-
- inline comm::operator double() { return double(x); }
- inline comm::operator float() { return float(x); }
- inline comm::operator int() { return int(x); }
- inline comm::operator long() { return long(x); }
-
- ostream& operator<<(ostream &s, comm d) {
- double absval = d.x >= 0 ? d.x : -d.x; // Absolute value of d
- int precis = s.precision(); // Digits to right of
- decimal
- double precismag = pow(10, precis);
- absval = long(absval * precismag) / precismag;
- // Round to req'd precision
- double base = absval;
- int neg = d.x >= 0 ? FALSE : TRUE; // Negative sign
- needed
- int digits = // Digits to left of
- decimal
- ((base == 0) ? 0 : max(0, floor(log10(base)))) + 1;
- int commas = floor((digits - 1) / 3); // Number of commas
- needed
- int decpt = precis > 0 ? TRUE : FALSE; // Decimal point
- needed
- double order = pow(10, commas * 3); // 1, 10^3, 10^6,
- 10^9, etc.
-
- // Set up formatting based on current field width for the stream.
- // Fill width with whitespace to right justify value.
- long flagsave = s.flags();
- int wid = s.width();
- s.setf(ios::fixed, ios::showpoint);
- s.width(0);
- s.precision(0);
- int needed = neg + digits + commas + decpt + precis;
- for (int i = 1; i <= wid - needed; i++)
- s << " ";
-
- // Now write out the value, with commas
- if (neg)
- s << "-";
- double rem;
- while (order > 1) {
- rem = floor(base / order);
- if (base == absval)
- s << int(rem) << ",";
- else
- s << setw(3) << setfill('0') << int(rem) << ",";
- base -= rem * order;
- order /= 1000;
- }
- if (base == absval)
- s << setprecision(precis) << base;
- else
- s << setw(3 + decpt + precis) << setfill('0')
- << setprecision(precis) << base;
-
- s.flags(flagsave);
- return s;
- }
-
- ***********************************************
-
- And finally, in implementation just cast your value to type "comm", as
- follows:
-
- fptr << " Avg balance: $ " << comm(total_bal / loan_count) << "\n";
-
- Feel free to e-mail me if questions.
- --------------------
- John Pirie
- Cohane Rafferty Securities, Inc.
- Harrison, NY
- "I'd keep playing -- I don't think the heavy stuff's comin' down for quite
- a while yet."
-